<?php

namespace App\Library\Models;

use App\Library\Requests\Base\BaseDTORequest;
use App\Library\Requests\Base\BasePageRequest;
use App\Library\Traits\BaseModelTrait;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;

class Entity extends Model
{
    use HasFactory, BaseModelTrait;

    protected $hidden = ['deleted_at'];

    const null CREATED_AT = null;

    const null UPDATED_AT = null;

    /**
     * getSerialNumber
     * @param int $num
     * @param array $fillAble
     * @param string $column
     * @return string
     */
    public static function getSerialNumber(int $num = 20, array $fillAble = [], string $column = 'serialNumber'): string
    {
        $array = [];
        while (true) {
            if ($num === 20) $number = serialNumber($num);
            else if ($num === 6) $number = random();
            else $number = random(mt_rand(6, 10), 1);
            if (in_array($number, $array)) continue;
            else if (in_array('deleted_at', $fillAble)) {
                $exists = self::query()->withTrashed()->where(humpToLine($column), $number)->exists();
            } else $exists = self::query()->where(humpToLine($column), $number)->exists();
            if (!$exists) return $number;
            $array[] = $number;
        }
    }

    /**
     * findBySerialNumber
     * @param BaseDTORequest|string $request
     * @param array|string $columns
     * @return Model|null
     */
    public static function findBySerialNumber(BaseDTORequest|string $request, array|string $columns = ['*']): ?Model
    {
        return self::query()
            ->where('serial_number', $request instanceof BaseDTORequest ? $request->serialNumber : $request)
            ->first(humpToLine($columns));
    }

    /**
     * dateFilter
     * @param BasePageRequest $request
     * @param Builder $builder
     * @param string $column
     * @return void
     */
    public static function dateFilter(BasePageRequest $request, Builder $builder, string $column): void
    {
        $column = humpToLine($column);
        if (!is_null($request->startAt)) {
            $builder->where($column, '>=', now()->parse($request->startAt)->startOfDay()->timestamp);
            $request->offsetUnset('startAt');
        }
        if (!is_null($request->endAt)) {
            $builder->where($column, '<=', now()->parse($request->endAt)->endOfDay()->timestamp);
            $request->offsetUnset('endAt');
        }
    }
}
